﻿using System;
using System.Collections.Generic;
using UnityEngine;

// Token: 0x02000446 RID: 1094
public class CombinedMesh : MonoBehaviour
{
	// Token: 0x06001E8E RID: 7822 RVA: 0x000C4980 File Offset: 0x000C2B80
	public void CancelCombining()
	{
		this.m_bCancelled = true;
	}

	// Token: 0x06001E8F RID: 7823 RVA: 0x000C4989 File Offset: 0x000C2B89
	public bool CombiningCancelled()
	{
		return this.m_bCancelled;
	}

	// Token: 0x06001E90 RID: 7824 RVA: 0x000C4994 File Offset: 0x000C2B94
	public void TransformObjInfoMeshVectorsToLocal(Transform newTransform)
	{
		foreach (CombinedMesh.ObjectInfo objectInfo in this.m_listObjectInfo)
		{
			if (objectInfo.mesh.normals != null && objectInfo.av3NormalsWorld != null)
			{
				Vector3[] array = new Vector3[objectInfo.av3NormalsWorld.Length];
				objectInfo.av3NormalsWorld.CopyTo(array, 0);
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = newTransform.InverseTransformDirection(array[i]);
				}
				objectInfo.mesh.normals = array;
			}
			if (objectInfo.mesh.tangents != null)
			{
				Vector4[] array2 = new Vector4[objectInfo.av4TangentsWorld.Length];
				objectInfo.av4TangentsWorld.CopyTo(array2, 0);
				for (int j = 0; j < array2.Length; j++)
				{
					Vector3 direction = new Vector3(array2[j].x, array2[j].y, array2[j].z);
					direction = newTransform.InverseTransformDirection(direction);
					array2[j] = new Vector4(direction.x, direction.y, direction.z, array2[j].w);
				}
				objectInfo.mesh.tangents = array2;
			}
		}
	}

	// Token: 0x06001E91 RID: 7825 RVA: 0x000C4B30 File Offset: 0x000C2D30
	public int GetObjectCount()
	{
		return this.m_listObjectInfo.Count;
	}

	// Token: 0x06001E92 RID: 7826 RVA: 0x000C4B3D File Offset: 0x000C2D3D
	public CombinedMesh.ObjectInfo GetObjectInfo(int nIndex)
	{
		return this.m_listObjectInfo[nIndex];
	}

	// Token: 0x06001E93 RID: 7827 RVA: 0x000C4B4C File Offset: 0x000C2D4C
	public void Combine(CombinedMesh.CombineProgressDelegate progress)
	{
		this.m_listObjectInfo.Clear();
		this.m_dicMeshEntries.Clear();
		this.m_bCancelled = false;
		bool flag = false;
		bool flag2 = false;
		bool flag3 = false;
		bool flag4 = false;
		bool flag5 = false;
		Vector3 vector = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
		Vector3 vector2 = new Vector3(float.MinValue, float.MinValue, float.MinValue);
		int num = 0;
		foreach (MeshFilter meshFilter in this.MeshObjects)
		{
			if (progress != null)
			{
				progress("Preprocessing object " + meshFilter.name + "...", (float)num / (float)this.MeshObjects.Length);
			}
			if (this.m_bCancelled)
			{
				return;
			}
			if (!(meshFilter == null))
			{
				if (meshFilter.GetComponent<Renderer>() == null)
				{
					Debug.LogWarning(meshFilter.name + " has no mesh renderer available");
				}
				else
				{
					Mesh sharedMesh = meshFilter.sharedMesh;
					Vector3[] vertices = sharedMesh.vertices;
					for (int j = 0; j < vertices.Length; j++)
					{
						Vector3 vector3 = meshFilter.transform.TransformPoint(vertices[j]);
						if (vector3.x < vector.x)
						{
							vector.x = vector3.x;
						}
						if (vector3.y < vector.y)
						{
							vector.y = vector3.y;
						}
						if (vector3.z < vector.z)
						{
							vector.z = vector3.z;
						}
						if (vector3.x > vector2.x)
						{
							vector2.x = vector3.x;
						}
						if (vector3.y > vector2.y)
						{
							vector2.y = vector3.y;
						}
						if (vector3.z > vector2.z)
						{
							vector2.z = vector3.z;
						}
					}
					if (sharedMesh.normals != null && sharedMesh.normals.Length > 0)
					{
						flag = true;
					}
					if (sharedMesh.tangents != null && sharedMesh.tangents.Length > 0)
					{
						flag2 = true;
					}
					if (sharedMesh.colors != null && sharedMesh.colors.Length > 0)
					{
						flag3 = true;
					}
					if (sharedMesh.colors32 != null && sharedMesh.colors32.Length > 0)
					{
						flag3 = true;
					}
					if (sharedMesh.uv != null && sharedMesh.uv.Length > 0)
					{
						flag4 = true;
					}
					if (sharedMesh.uv2 != null && sharedMesh.uv2.Length > 0)
					{
						flag5 = true;
					}
					for (int k = 0; k < sharedMesh.subMeshCount; k++)
					{
						CombinedMesh.MaterialMeshInfo item = new CombinedMesh.MaterialMeshInfo(meshFilter.transform, sharedMesh, k);
						Material key = meshFilter.GetComponent<Renderer>().sharedMaterials[k];
						if (!this.m_dicMeshEntries.ContainsKey(key))
						{
							this.m_dicMeshEntries.Add(key, new List<CombinedMesh.MaterialMeshInfo>());
						}
						this.m_dicMeshEntries[key].Add(item);
					}
					this.m_listObjectInfo.Add(new CombinedMesh.ObjectInfo(meshFilter.GetComponent<Renderer>().sharedMaterials, sharedMesh, meshFilter.transform, meshFilter.transform.localToWorldMatrix));
				}
			}
		}
		if (this.m_dicMeshEntries.Count > 0)
		{
			Vector3 position = base.transform.position;
			switch (this.PivotMode)
			{
			case CombinedMesh.EPivotMode.Keep:
				position = base.transform.position;
				break;
			case CombinedMesh.EPivotMode.Center:
				position = (vector2 + vector) * 0.5f;
				break;
			case CombinedMesh.EPivotMode.BottomCenter:
				position = (vector2 + vector) * 0.5f;
				position.y = vector.y;
				break;
			case CombinedMesh.EPivotMode.TopCenter:
				position = (vector2 + vector) * 0.5f;
				position.y = vector2.y;
				break;
			case CombinedMesh.EPivotMode.Min:
				position = vector;
				break;
			case CombinedMesh.EPivotMode.Max:
				position = vector2;
				break;
			}
			Vector3 position2 = base.transform.position;
			Quaternion rotation = base.transform.rotation;
			Vector3 localScale = base.transform.localScale;
			base.transform.position = position;
			base.transform.rotation = Quaternion.identity;
			base.transform.localScale = Vector3.one;
			Matrix4x4 worldToLocalMatrix = base.transform.worldToLocalMatrix;
			if (this.KeepPosition)
			{
				base.transform.position = position2;
				base.transform.rotation = rotation;
				base.transform.localScale = localScale;
			}
			Material[] array = new Material[this.m_dicMeshEntries.Keys.Count];
			this.m_dicMeshEntries.Keys.CopyTo(array, 0);
			foreach (CombinedMesh.ObjectInfo objectInfo in this.m_listObjectInfo)
			{
				objectInfo.mtxLocal = worldToLocalMatrix * objectInfo.mtxLocal;
			}
			List<int>[] array2 = new List<int>[this.m_dicMeshEntries.Count];
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector4> list3 = new List<Vector4>();
			List<Color32> list4 = new List<Color32>();
			List<Vector2> list5 = new List<Vector2>();
			List<Vector2> list6 = new List<Vector2>();
			Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
			int num2 = 0;
			foreach (List<CombinedMesh.MaterialMeshInfo> list7 in this.m_dicMeshEntries.Values)
			{
				array2[num2] = new List<int>();
				int num3 = 0;
				foreach (CombinedMesh.MaterialMeshInfo materialMeshInfo in list7)
				{
					if (progress != null)
					{
						progress("Combining submesh for material " + array[num2].name + "...", (float)num3 / (float)list7.Count);
					}
					if (this.m_bCancelled)
					{
						return;
					}
					int num4 = list.Count;
					if (dictionary.ContainsKey(materialMeshInfo.transform.gameObject))
					{
						num4 = dictionary[materialMeshInfo.transform.gameObject];
					}
					else
					{
						Matrix4x4 localToWorldMatrix = materialMeshInfo.transform.localToWorldMatrix;
						Matrix4x4 matrix4x = worldToLocalMatrix * localToWorldMatrix;
						dictionary.Add(materialMeshInfo.transform.gameObject, num4);
						int vertexCount = materialMeshInfo.mesh.vertexCount;
						Vector3[] vertices2 = materialMeshInfo.mesh.vertices;
						for (int l = 0; l < vertices2.Length; l++)
						{
							vertices2[l] = matrix4x.MultiplyPoint3x4(vertices2[l]);
						}
						list.AddRange(vertices2);
						if (flag)
						{
							bool flag6 = true;
							if (materialMeshInfo.mesh.normals != null && materialMeshInfo.mesh.normals.Length > 0)
							{
								flag6 = false;
							}
							if (flag6)
							{
								Debug.LogWarning(string.Format("Object {0} has mesh with no vertex normals, and some other objects have them. Dummy normals have been added", materialMeshInfo.transform.name));
							}
							Vector3[] array3 = (!flag6) ? materialMeshInfo.mesh.normals : new Vector3[vertexCount];
							for (int m = 0; m < array3.Length; m++)
							{
								array3[m] = materialMeshInfo.transform.TransformDirection(array3[m]);
								array3[m] = base.transform.InverseTransformDirection(array3[m]);
							}
							list2.AddRange(array3);
						}
						if (flag2)
						{
							bool flag7 = true;
							if (materialMeshInfo.mesh.tangents != null && materialMeshInfo.mesh.tangents.Length > 0)
							{
								flag7 = false;
							}
							if (flag7)
							{
								Debug.LogWarning(string.Format("Object {0} has mesh with no vertex tangents, and some other objects have them. Dummy tangents have been added", materialMeshInfo.transform.name));
							}
							Vector4[] array4 = (!flag7) ? materialMeshInfo.mesh.tangents : new Vector4[vertexCount];
							for (int n = 0; n < array4.Length; n++)
							{
								Vector3 direction = new Vector3(array4[n].x, array4[n].y, array4[n].z);
								direction = materialMeshInfo.transform.TransformDirection(direction);
								direction = base.transform.InverseTransformDirection(direction);
								array4[n] = new Vector4(direction.x, direction.y, direction.z, (!flag7) ? array4[n].w : 1f);
							}
							list3.AddRange(array4);
						}
						if (flag3)
						{
							bool flag8 = false;
							bool flag9 = false;
							bool flag10 = true;
							if (materialMeshInfo.mesh.colors != null && materialMeshInfo.mesh.colors.Length > 0)
							{
								flag8 = true;
								flag10 = false;
							}
							if (materialMeshInfo.mesh.colors32 != null && materialMeshInfo.mesh.colors32.Length > 0)
							{
								flag9 = true;
								flag10 = false;
							}
							if (flag10)
							{
								Debug.LogWarning(string.Format("Object {0} has mesh with no vertex colors, and some other objects have them. Dummy colors have been added", materialMeshInfo.transform.name));
							}
							Color32[] array5 = null;
							if (flag10)
							{
								array5 = new Color32[vertexCount];
							}
							else if (flag8)
							{
								array5 = new Color32[vertexCount];
								Color[] colors = materialMeshInfo.mesh.colors;
								for (int num5 = 0; num5 < vertexCount; num5++)
								{
									array5[num5] = colors[num5];
								}
							}
							else if (flag9)
							{
								array5 = materialMeshInfo.mesh.colors32;
							}
							list4.AddRange(array5);
						}
						if (flag4)
						{
							bool flag11 = true;
							if (materialMeshInfo.mesh.uv != null && materialMeshInfo.mesh.uv.Length > 0)
							{
								flag11 = false;
							}
							if (flag11)
							{
								Debug.LogWarning(string.Format("Object {0} has mesh with no vertex mapping (uv), and some other objects have them. Dummy mapping has been added", materialMeshInfo.transform.name));
							}
							Vector2[] collection = (!flag11) ? materialMeshInfo.mesh.uv : new Vector2[vertexCount];
							list5.AddRange(collection);
						}
						if (flag5)
						{
							bool flag12 = true;
							if (materialMeshInfo.mesh.uv2 != null && materialMeshInfo.mesh.uv2.Length > 0)
							{
								flag12 = false;
							}
							if (flag12)
							{
								Debug.LogWarning(string.Format("Object {0} has mesh with no vertex mapping (uv2), and some other objects have them. Dummy mapping has been added", materialMeshInfo.transform.name));
							}
							Vector2[] collection2 = (!flag12) ? materialMeshInfo.mesh.uv2 : new Vector2[vertexCount];
							list6.AddRange(collection2);
						}
					}
					int[] triangles = materialMeshInfo.mesh.GetTriangles(materialMeshInfo.nSubMesh);
					for (int num6 = 0; num6 < triangles.Length; num6++)
					{
						array2[num2].Add(triangles[num6] + num4);
					}
					num3++;
				}
				num2++;
			}
			if (!this.m_bCancelled)
			{
				if (progress != null)
				{
					progress("Building mesh...", 1f);
				}
				MeshFilter meshFilter2 = base.gameObject.GetComponent<MeshFilter>();
				if (meshFilter2 == null)
				{
					meshFilter2 = base.gameObject.AddComponent<MeshFilter>();
				}
				if (base.GetComponent<Renderer>() == null)
				{
					base.gameObject.AddComponent<MeshRenderer>();
				}
				base.GetComponent<Renderer>().sharedMaterials = array;
				int num7 = 65000;
				if (list.Count > num7)
				{
					Debug.LogWarning(string.Concat(new object[]
					{
						"Warning! vertex count = ",
						list.Count,
						". You may be hitting Unity's vertex count limit (",
						num7,
						"). Please try combining less objects."
					}));
				}
				Mesh mesh = new Mesh();
				mesh.vertices = list.ToArray();
				if (flag)
				{
					mesh.normals = list2.ToArray();
				}
				if (flag2)
				{
					mesh.tangents = list3.ToArray();
				}
				if (flag3)
				{
					mesh.colors32 = list4.ToArray();
				}
				if (flag4)
				{
					mesh.uv = list5.ToArray();
				}
				if (flag5)
				{
					mesh.uv2 = list6.ToArray();
				}
				mesh.subMeshCount = array2.Length;
				for (int num8 = 0; num8 < array2.Length; num8++)
				{
					mesh.SetTriangles(array2[num8].ToArray(), num8);
				}
				meshFilter2.sharedMesh = mesh;
			}
		}
		else
		{
			Debug.LogWarning("No meshes were combined because none were found.");
		}
	}

	// Token: 0x04001F0A RID: 7946
	public bool SaveMeshAsset;

	// Token: 0x04001F0B RID: 7947
	public bool KeepPosition = true;

	// Token: 0x04001F0C RID: 7948
	public CombinedMesh.EPivotMode PivotMode = CombinedMesh.EPivotMode.Center;

	// Token: 0x04001F0D RID: 7949
	public MeshFilter[] MeshObjects;

	// Token: 0x04001F0E RID: 7950
	public GameObject RootNode;

	// Token: 0x04001F0F RID: 7951
	private bool m_bCancelled;

	// Token: 0x04001F10 RID: 7952
	[SerializeField]
	private List<CombinedMesh.ObjectInfo> m_listObjectInfo = new List<CombinedMesh.ObjectInfo>();

	// Token: 0x04001F11 RID: 7953
	private Dictionary<Material, List<CombinedMesh.MaterialMeshInfo>> m_dicMeshEntries = new Dictionary<Material, List<CombinedMesh.MaterialMeshInfo>>();

	// Token: 0x02000447 RID: 1095
	// (Invoke) Token: 0x06001E95 RID: 7829
	public delegate void CombineProgressDelegate(string strMessage, float fT);

	// Token: 0x02000448 RID: 1096
	[Serializable]
	public class ObjectInfo
	{
		// Token: 0x06001E98 RID: 7832 RVA: 0x000C58BC File Offset: 0x000C3ABC
		public ObjectInfo(Material[] aMaterials, Mesh mesh, Transform transform, Matrix4x4 mtxLocal)
		{
			this.aMaterials = new Material[aMaterials.Length];
			aMaterials.CopyTo(this.aMaterials, 0);
			this.mesh = UnityEngine.Object.Instantiate<Mesh>(mesh);
			this.v3LocalPosition = transform.localPosition;
			this.qLocalRotation = transform.localRotation;
			this.v3LocalScale = transform.localScale;
			this.mtxLocal = mtxLocal;
			this.mtxWorld = transform.localToWorldMatrix;
			if (mesh.normals != null)
			{
				this.av3NormalsWorld = mesh.normals;
				for (int i = 0; i < this.av3NormalsWorld.Length; i++)
				{
					this.av3NormalsWorld[i] = this.mtxWorld.MultiplyVector(this.av3NormalsWorld[i]);
				}
			}
			if (mesh.tangents != null)
			{
				this.av4TangentsWorld = mesh.tangents;
				for (int j = 0; j < this.av4TangentsWorld.Length; j++)
				{
					Vector3 vector = new Vector3(this.av4TangentsWorld[j].x, this.av4TangentsWorld[j].y, this.av4TangentsWorld[j].z);
					vector = this.mtxWorld.MultiplyVector(vector);
					this.av4TangentsWorld[j] = new Vector4(vector.x, vector.y, vector.z, this.av4TangentsWorld[j].w);
				}
			}
		}

		// Token: 0x04001F12 RID: 7954
		public Material[] aMaterials;

		// Token: 0x04001F13 RID: 7955
		public Mesh mesh;

		// Token: 0x04001F14 RID: 7956
		public Vector3 v3LocalPosition;

		// Token: 0x04001F15 RID: 7957
		public Quaternion qLocalRotation;

		// Token: 0x04001F16 RID: 7958
		public Vector3 v3LocalScale;

		// Token: 0x04001F17 RID: 7959
		public Matrix4x4 mtxLocal;

		// Token: 0x04001F18 RID: 7960
		public Matrix4x4 mtxWorld;

		// Token: 0x04001F19 RID: 7961
		public Vector3[] av3NormalsWorld;

		// Token: 0x04001F1A RID: 7962
		public Vector4[] av4TangentsWorld;
	}

	// Token: 0x02000449 RID: 1097
	private class MaterialMeshInfo
	{
		// Token: 0x06001E99 RID: 7833 RVA: 0x000C5A3E File Offset: 0x000C3C3E
		public MaterialMeshInfo(Transform transform, Mesh mesh, int nSubMesh)
		{
			this.transform = transform;
			this.mesh = mesh;
			this.nSubMesh = nSubMesh;
		}

		// Token: 0x04001F1B RID: 7963
		public Transform transform;

		// Token: 0x04001F1C RID: 7964
		public Mesh mesh;

		// Token: 0x04001F1D RID: 7965
		public int nSubMesh;
	}

	// Token: 0x0200044A RID: 1098
	public enum EPivotMode
	{
		// Token: 0x04001F1F RID: 7967
		Keep,
		// Token: 0x04001F20 RID: 7968
		Center,
		// Token: 0x04001F21 RID: 7969
		BottomCenter,
		// Token: 0x04001F22 RID: 7970
		TopCenter,
		// Token: 0x04001F23 RID: 7971
		Min,
		// Token: 0x04001F24 RID: 7972
		Max
	}
}
